/*
 *
 *   Copyright (C) 2005 by Raymond Huang
 *   plushuang at users.sourceforge.net
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  In addition, as a special exception, the copyright holders give
 *  permission to link the code of portions of this program with the
 *  OpenSSL library under certain conditions as described in each
 *  individual source file, and distribute linked combinations
 *  including the two.
 *  You must obey the GNU Lesser General Public License in all respects
 *  for all of the code used other than OpenSSL.  If you modify
 *  file(s) with this exception, you may extend this exception to your
 *  version of the file(s), but you are not obligated to do so.  If you
 *  do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source
 *  files in the program, then also delete it here.
 *
 */

#include <gdk/gdkkeysyms.h>
#include "node_list_model.h"
#include "download_dialog.h"
#include "category_tree_view.h"
#include "urlgfe_util.h"
#include <urlglib/ug_i18n.h>

// signal handler ---------------------------------------------------

static gboolean on_key_press_event (GtkWidget* widget,
                                    GdkEventKey *event,
                                    DownloadDialog *dd)
{
	int keyval = event->keyval;

	if (keyval == GDK_Return || keyval == GDK_KP_Enter) {
		gtk_dialog_response (dd->self, GTK_RESPONSE_OK);
		return TRUE;
	}
	return FALSE;
}

static void on_response (GtkDialog *dlg, gint response, gpointer data)
{
	DownloadDialog* dd = data;
	const gchar* path;

	if (response == GTK_RESPONSE_OK) {
		path = gtk_entry_get_text (GTK_ENTRY (dd->dinfo_view.entry_dir));
		directory_history_set (path);
	}
}

// DownloadDialog functions ------------------------------------------

DownloadDialog* download_dialog_new (GtkWindow* parent, gboolean modal)
{
	DownloadDialog* dd = g_malloc (sizeof (DownloadDialog));

	download_dialog_init (dd, parent);
	gtk_window_set_modal (GTK_WINDOW (dd->self), modal);
	return dd;
}

void  download_dialog_destroy (DownloadDialog* dd)
{
	if (dd) {
		dd->finalize (dd);
		g_free (dd);
	}
}

const char* download_dialog_get_error_string (DownloadDialog* dd)
{
	gint   field_state;

	if (dd->rnode && download_dialog_get_category (dd) == NULL)
		return _("You must select a category.");

	field_state = download_info_view_check_field (&dd->dinfo_view);
	switch (field_state) {
	case DOWNLOAD_INFO_UNCOMPLETE:
		return _("You must complete field : \"Save to\".");
	case DOWNLOAD_INFO_UNCOMPLETE_MULTIPlE:
		return _("You must complete field : \"URL\" ,\"Save to\" ,and \"Rename\".");
	case DOWNLOAD_INFO_UNCOMPLETE_URL:
		return _("Invalid URL.");
	case DOWNLOAD_INFO_COMPLETE:
	default:
		return NULL;
	}
}

gint  download_dialog_run (DownloadDialog* dd)
{
	while (1) {
		if (gtk_dialog_run (dd->self) != GTK_RESPONSE_OK)
			break;
		if (download_dialog_handle_error (dd) == FALSE)
			return GTK_RESPONSE_OK;
	}
	return GTK_RESPONSE_CANCEL;
}

gboolean download_dialog_handle_error (DownloadDialog* dd)
{
	const gchar* msg;
	GtkWidget* dialog;

	msg = download_dialog_get_error_string (dd);
	if (msg) {
		dialog = gtk_message_dialog_new (GTK_WINDOW (dd->self),
		                                 GTK_DIALOG_DESTROY_WITH_PARENT,
		                                 GTK_MESSAGE_ERROR,
		                                 GTK_BUTTONS_CLOSE,
		                                 msg);
		gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(dd->self));
		g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
		gtk_widget_show (dialog);
		return TRUE;
	}
	return FALSE;
}

void  download_dialog_set_title (DownloadDialog* dd, const gchar* title)
{
	gtk_window_set_title (GTK_WINDOW (dd->self), title ? title : "");
}

void  download_dialog_set_modal (DownloadDialog* dd, gboolean modal)
{
	gtk_window_set_modal (GTK_WINDOW (dd->self), modal);
}

// category ---

static void on_cursor_changed (GtkTreeView* treeview, DownloadDialog* dd)
{
	CategoryNode* cnode = download_dialog_get_category (dd);

	if (cnode)
		download_info_view_apply (&dd->dinfo_view, cnode->download_default);
}

void  download_dialog_set_category (DownloadDialog* dd, RootNode* rnode, CategoryNode* cnode)
{
	GtkWidget*   label;
	GtkTreePath* path;
	int  index;

	dd->rnode    = rnode;
	dd->treeview = category_list_view_new ();
	dd->model    = (GtkTreeModel*)node_list_model_new (BASE_NODE (rnode));
	gtk_tree_view_set_headers_visible (dd->treeview, FALSE);
	gtk_tree_view_set_model (dd->treeview, dd->model);
	g_object_unref (dd->model);

	label = gtk_label_new (_("Select a Category"));
	dd->title_category = label;
	gtk_widget_show (label);
	gtk_table_attach (dd->table, label, 0, 1, 0, 1,
	                  GTK_SHRINK, GTK_SHRINK, 3, 3);

	dd->scrolled = (GtkScrolledWindow*) gtk_scrolled_window_new (NULL, NULL);
	gtk_widget_set_size_request (GTK_WIDGET (dd->scrolled), 120, 150);
	gtk_scrolled_window_set_shadow_type (dd->scrolled, GTK_SHADOW_IN);
	gtk_scrolled_window_set_policy (dd->scrolled, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_container_add (GTK_CONTAINER (dd->scrolled), GTK_WIDGET (dd->treeview));
	gtk_widget_show_all (GTK_WIDGET (dd->scrolled));
	gtk_table_attach (dd->table, GTK_WIDGET (dd->scrolled), 0, 1, 1, 2,
	                  GTK_FILL, GTK_FILL | GTK_EXPAND, 3, 3);

	g_signal_connect (dd->treeview, "cursor-changed",
	                  G_CALLBACK (on_cursor_changed), dd);

	// set cursor
	index = (cnode) ? root_node_category_position (rnode, cnode) : 0;
	path = gtk_tree_path_new ();
	gtk_tree_path_prepend_index (path, index);
	gtk_tree_view_set_cursor (dd->treeview, path, NULL, FALSE);
	gtk_tree_path_free (path);
}

CategoryNode* download_dialog_get_category (DownloadDialog* dd)
{
	GtkTreePath*      path;
	GtkTreeSelection* selection;
	int  index;

	selection = gtk_tree_view_get_selection (dd->treeview);
	if (gtk_tree_selection_get_selected (selection, NULL, NULL) == FALSE)
		return NULL;

	gtk_tree_view_get_cursor (dd->treeview, &path, NULL);
	index = *gtk_tree_path_get_indices (path);
	gtk_tree_path_free (path);

	return root_node_nth_category (dd->rnode, index);
}

// protected functions
void download_dialog_init (DownloadDialog*dd, GtkWindow* parent)
{
	download_info_view_init (&dd->dinfo_view);

	dd->finalize = download_dialog_finalize;
	dd->rnode = NULL;
	dd->self = (GtkDialog*)gtk_dialog_new ();
	gtk_window_set_destroy_with_parent (GTK_WINDOW (dd->self), TRUE);
	g_object_set (dd->self, "has-separator", FALSE, NULL);

	dd->button_skip = gtk_dialog_add_button (dd->self, _("Ski_p"), GTK_RESPONSE_REJECT);
	gtk_widget_hide (dd->button_skip);
	gtk_widget_set_sensitive (dd->button_skip, FALSE);

	gtk_dialog_add_button (dd->self, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
	gtk_dialog_add_button (dd->self, GTK_STOCK_OK, GTK_RESPONSE_OK);

	gtk_window_set_title (GTK_WINDOW (dd->self), _("Download property"));

	if (parent)
		gtk_window_set_transient_for (GTK_WINDOW (dd->self), parent);

	gtk_window_set_resizable (GTK_WINDOW(dd->self), FALSE);
	gtk_dialog_set_default_response (dd->self, GTK_RESPONSE_OK);
	dd->dinfo_view.parent = GTK_WINDOW (dd->self);

	dd->table = (GtkTable*) gtk_table_new (3, 2, FALSE);
	gtk_table_attach (dd->table, dd->dinfo_view.self, 1, 2, 0, 3,
	                  GTK_FILL, GTK_FILL | GTK_EXPAND, 3, 3);
	gtk_widget_show (GTK_WIDGET (dd->table));
	gtk_box_pack_start (GTK_BOX (dd->self->vbox), GTK_WIDGET (dd->table), TRUE, TRUE, 0);

	g_signal_connect (dd->self, "response", G_CALLBACK (on_response), dd);
	// signal for DownloadInfoView
	g_signal_connect (dd->dinfo_view.entry_url, "key-press-event",
	                  G_CALLBACK (on_key_press_event), dd);
	g_signal_connect (dd->dinfo_view.entry_dir, "key-press-event",
	                  G_CALLBACK (on_key_press_event), dd);
	g_signal_connect (dd->dinfo_view.entry_filename, "key-press-event",
	                  G_CALLBACK (on_key_press_event), dd);
	g_signal_connect (dd->dinfo_view.entry_referer, "key-press-event",
	                  G_CALLBACK (on_key_press_event), dd);
	g_signal_connect (dd->dinfo_view.entry_username, "key-press-event",
	                  G_CALLBACK (on_key_press_event), dd);
	g_signal_connect (dd->dinfo_view.entry_password, "key-press-event",
	                  G_CALLBACK (on_key_press_event), dd);
}

void download_dialog_finalize (DownloadDialog*dd)
{
	gtk_widget_destroy (GTK_WIDGET (dd->self));
}
